﻿#region Imports
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using CommonUtilities.Enums;
using CommonUtilities.Extensions;
using CommonUtilities.Util;
#endregion

namespace CommonUtilities.Events
{
    /// <summary>
    /// Contains custom events shared by multiple controls
    /// <para>(class cannot be instantiated)</para>
    /// </summary>
    public static class EventList
    {
        #region Declarations
        #region Constant declarations
        /// <summary>
        /// Constant for showing drop-down
        /// </summary>
        public const int CB_SHOWDROPDOWN = 0x14F;
        #endregion

        #region Method declarations
        [DllImport("user32.dll")]
        private static extern int SendMessage(int hWnd, int msg, int wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
        internal static extern IntPtr GetFocus();
        #endregion
        #endregion

        #region Properties
        /// <summary>
        /// Last focussed control
        /// </summary>
        public static Control LastFocused { get; set; }
        #endregion

        #region Events
        /// <summary>
        /// Selects the text
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        public static void TextControl_SelectAll(object sender, KeyEventArgs e)
        {
            Utilities.SelectAllText(sender, Form.ModifierKeys, e.KeyCode);
        }

        /*
        private void TextControl_SelectAll(object sender, KeyEventArgs e)
        {
            //char chrPressed = (char)e.KeyValue;
            //e.SuppressKeyPress = System.IO.Path.GetInvalidPathChars().Contains(chrPressed); // && !System.IO.Path.GetInvalidFileNameChars().Contains(chrPressed);

            //string invalidChars = @"/\:*?""<>|";
            //char[] invalid = invalidChars.ToCharArray();
            //char chrPressed = (char)e.KeyValue;
            //e.SuppressKeyPress = invalid.Contains(chrPressed);

            //if (e.KeyCode == e.KeyData)
            //{
            //    MessageBox.Show(e.KeyValue.ToString());
            //}

            //MessageBox.Show(Convert.ToChar(e.KeyValue).ToString());

            List<Keys> IgnoreKeys = new List<Keys>();
            IgnoreKeys.Add(Keys.ShiftKey);
            IgnoreKeys.Add(Keys.CapsLock);
            IgnoreKeys.Add(Keys.ControlKey);
            IgnoreKeys.Add(Keys.Back);
            IgnoreKeys.Add(Keys.Delete);

            IgnoreKeys.Add(Keys.PageUp);
            IgnoreKeys.Add(Keys.PageDown);
            IgnoreKeys.Add(Keys.Home);
            IgnoreKeys.Add(Keys.End);
            IgnoreKeys.Add(Keys.NumLock);
            IgnoreKeys.Add(Keys.Scroll);


            if (!IgnoreKeys.Contains(e.KeyCode) && Form.ModifierKeys != Keys.Control)
            {
                List<Keys> invalidKeys = new List<Keys>();
                invalidKeys.Add(Keys.Multiply);
                invalidKeys.Add(Keys.Divide);
                invalidKeys.Add(Keys.OemQuestion);
                invalidKeys.Add(Keys.Oemtilde);

                string inv = @"""<>";

                e.SuppressKeyPress = invalidKeys.Contains(e.KeyCode) || (Form.ModifierKeys == Keys.Shift && e.KeyCode == Keys.OemPipe) || (Form.ModifierKeys == Keys.Shift && e.KeyCode == Keys.D8) || (!Text.Contains(":") ? false : Form.ModifierKeys == Keys.Shift && e.KeyCode == Keys.OemSemicolon);
            }
        }

        /// <summary>
        /// Selects the text
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        public static void TextControl_SelectAll(object sender, KeyEventArgs e)
        {
            BRUtilities.SelectAllText(sender, Form.ModifierKeys, e.KeyCode);
        }
        */

        /// <summary>
        /// Shows drop-down of ComboBox
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        public static void ComboBox_ShowDropDown(object sender, EventArgs e)
        {
            ComboBox cmb = (ComboBox)sender;
            Form parent = cmb.FindForm();

            LastFocused = null;
            if (parent.ActiveControl != cmb) LastFocused = parent.ActiveControl; // EventList.GetFocusedControl(); // RKD

            cmb.Focus();
            EventList.ToggleDropDown(cmb, eShowHideType.Show);
        }

        /// <summary>
        /// Hides drop-down of ComboBox
        /// </summary>
        /// <param name="sender">Sender</param>
        /// <param name="e">EventArgs</param>
        public static void ComboBox_HideDropDown(object sender, EventArgs e)
        {
            ComboBox cmb = (ComboBox)sender;

            EventList.ToggleDropDown(cmb, eShowHideType.Hide);
            if (!LastFocused.IsNull()) LastFocused.Focus();
        }
        #endregion

        #region Methods
        /// <summary>
        /// Toggles drop-down of ComboBox
        /// </summary>
        /// <param name="cmb">ComboBox</param>
        /// <param name="typeShowHide">Specifies if the drop-down is to be shown/hidden or toggled</param>
        public static void ToggleDropDown(ComboBox cmb, eShowHideType typeShowHide)
        {
            switch (typeShowHide)
            {
                case eShowHideType.Show:
                    //SendMessage(cmb.Handle.ToInt32(), CB_SHOWDROPDOWN, 1, IntPtr.Zero); // RKD
                    cmb.DroppedDown = true;
                    break;
                case eShowHideType.Toggle:
                    cmb.DroppedDown = !cmb.DroppedDown;
                    break;
                case eShowHideType.Hide:
                default:
                    cmb.DroppedDown = false;
                    break;
            }
        }

        /// <summary>
        /// Gets control currently in focus
        /// </summary>
        /// <returns></returns>
        public static Control GetFocusedControl()
        {
            Control focusedControl = null;
            IntPtr focusedHandle = GetFocus(); // To get hold of the focused control

            if (focusedHandle != IntPtr.Zero)
                focusedControl = Control.FromHandle(focusedHandle); // Note that if the focused Control is not a .Net control, then this will return null.

            return focusedControl;
        }

        public static string ToString()
        {
            return Utilities.ToString(typeof(EventList));
        }
        #endregion
    }
}
